// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraAnimInstance.h"
#include "AbilitySystemGlobals.h"
#include "Character/LyraCharacter.h"
#include "Character/LyraCharacterMovementComponent.h"

#if WITH_EDITOR
#include "Misc/DataValidation.h"
#endif

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraAnimInstance)

/**
 * 构造函数。
 * @param ObjectInitializer 对象初始化器
 */
ULyraAnimInstance::ULyraAnimInstance(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

/**
 * 使用能力系统组件初始化动画实例。
 * @param ASC 能力系统组件指针
 */
void ULyraAnimInstance::InitializeWithAbilitySystem(UAbilitySystemComponent* ASC)
{
	check(ASC); // 检查ASC是否有效

	GameplayTagPropertyMap.Initialize(this, ASC); // 初始化游戏标签属性映射
}

#if WITH_EDITOR
/**
 * 数据验证函数，用于检查数据的有效性。
 * @param Context 数据验证上下文
 * @return 返回数据验证结果
 */
EDataValidationResult ULyraAnimInstance::IsDataValid(FDataValidationContext& Context) const
{
	Super::IsDataValid(Context); // 调用父类的数据验证

	GameplayTagPropertyMap.IsDataValid(this, Context); // 验证游戏标签属性映射的数据

	return ((Context.GetNumErrors() > 0) ? EDataValidationResult::Invalid : EDataValidationResult::Valid); // 根据错误数量返回验证结果
}
#endif // WITH_EDITOR

/**
 * 动画实例原生初始化函数。
 */
void ULyraAnimInstance::NativeInitializeAnimation()
{
	Super::NativeInitializeAnimation(); // 调用父类的原生初始化

	if (AActor* OwningActor = GetOwningActor()) // 获取拥有者Actor
	{
		if (UAbilitySystemComponent* ASC = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(OwningActor)) // 从Actor获取能力系统组件
		{
			InitializeWithAbilitySystem(ASC); // 使用能力系统初始化
		}
	}
}

/**
 * 动画实例原生更新函数。
 * @param DeltaSeconds 帧间隔时间
 */
void ULyraAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds); // 调用父类的原生更新

	const ALyraCharacter* Character = Cast<ALyraCharacter>(GetOwningActor()); // 获取拥有者Actor并转换为LyraCharacter
	if (!Character) // 如果Character为空
	{
		return; // 直接返回
	}

	ULyraCharacterMovementComponent* CharMoveComp = CastChecked<ULyraCharacterMovementComponent>(Character->GetCharacterMovement()); // 获取角色移动组件
	const FLyraCharacterGroundInfo& GroundInfo = CharMoveComp->GetGroundInfo(); // 获取地面信息
	GroundDistance = GroundInfo.GroundDistance; // 更新地面距离
}